home *** CD-ROM | disk | FTP | other *** search
- #include <wfc.h>
- #include "messages.h"
- #pragma hdrstop
-
- /*
- ** Author: Samuel R. Blackburn
- ** CI$: 76300,326
- ** Internet: sammy@sed.csc.com
- **
- ** This is freeware as always...
- **
- ** You can use it any way you like.
- **
- ** Sample program that watches other services and restarts them if they fail.
- **
- ** Registration Database Entries:
- **
- ** MachineName, REG_SZ, name of machine to monitor, default is local machine
- ** NumberOfSecondsBetweenChecks, REG_DWORD, how long to sleep between heartbeats
- ** Services, REG_MULTI_SZ, names of services to watch for
- **
- ** Demonstrates the following classes in action:
- ** CRegistry
- ** CService
- ** CServiceControlManager
- ** CServiceNameAndStatus
- */
-
- #if defined( _DEBUG )
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
-
- DWORD WINAPI worker_thread( LPVOID unused_parameter );
- VOID set_default_parameters( void );
-
- int __cdecl main( int argc, LPTSTR *argv )
- {
- if ( argc == 1 )
- {
- CService service( worker_thread );
- service.Initialize( "WatchDog" );
-
- return( EXIT_SUCCESS );
- }
-
- if ( argc == 2 )
- {
- if ( strcmpi( argv[ 1 ], "install" ) == 0 )
- {
- CServiceControlManager service_control_manager;
-
- service_control_manager.Open();
-
- if ( service_control_manager.Install( "WatchDog", "WatchDog", "%SystemRoot%\\System32\\WatchDog.exe" ) != TRUE )
- {
- printf( "Install failed, please see Application Log for details\n" );
- }
-
- set_default_parameters();
-
- return( EXIT_SUCCESS );
- }
- else if ( strcmpi( argv[ 1 ], "remove" ) == 0 )
- {
- CServiceControlManager service_control_manager;
-
- service_control_manager.Open();
-
- if ( service_control_manager.Remove( "WatchDog" ) != TRUE )
- {
- printf( "Removing failed, please see Application Log for details\n" );
- }
-
- return( EXIT_SUCCESS );
- }
- else if ( strcmpi( argv[ 1 ], "run" ) == 0 )
- {
- worker_thread( (LPVOID) 1 );
- return( EXIT_SUCCESS );
- }
- else
- {
- printf( "Samuel R. Blackburn, WFC Sample Application\nUsage: %s [install|remove]\n", argv[ 0 ] );
- }
- }
- else
- {
- printf( "Samuel R. Blackburn, WFC Sample Application\nUsage: %s [install|remove]\n", argv[ 0 ] );
- }
-
- return( EXIT_SUCCESS );
- }
-
-
- DWORD WINAPI worker_thread( LPVOID )
- {
- {
- CEventLog log( "WatchDog" );
-
- log.Report( CEventLog::eventInformation, 0, MSG_WATCHDOG_SERVICE_STARTED );
- }
-
- CStringArray names_of_services_to_keep_alive;
-
- DWORD number_of_seconds_to_sleep = 0;
-
- CString machine_name( "" );
-
- BOOL return_value = TRUE;
-
- {
- CRegistry registry;
-
- if ( registry.Connect( CRegistry::keyLocalMachine ) != TRUE )
- {
- return( 0 );
- }
-
- CString key_name( "SYSTEM\\CurrentControlSet\\Services\\WatchDog\\Parameters" );
-
- if ( registry.Open( key_name ) != TRUE )
- {
- return( 0 );
- }
-
- registry.GetValue( "Services", names_of_services_to_keep_alive );
- registry.GetValue( "NumberOfSecondsBetweenChecks", number_of_seconds_to_sleep );
- registry.GetValue( "MachineName", machine_name );
- }
-
- DWORD sleep_time = 1000 * number_of_seconds_to_sleep;
-
- if ( sleep_time < 2000 )
- {
- /*
- ** Minimum sleep time is 2 seconds, this give the OS time to do other things
- */
-
- sleep_time = 2000;
- }
-
- int number_of_services_to_keep_alive = names_of_services_to_keep_alive.GetSize();
-
- CServiceControlManager service_control_manager;
-
- /*
- ** Sleep for one minute, this is in case we are starting during boot-up. We want
- ** to give the service control manager time to start all necessary services before
- ** we begin restarting stopped services.
- */
-
- Sleep( 60 );
-
- do
- {
- if ( machine_name.IsEmpty() )
- {
- return_value = service_control_manager.Open( GENERIC_READ, NULL, (char *) NULL );
- }
- else
- {
- return_value = service_control_manager.Open( GENERIC_READ, NULL, machine_name );
- }
-
- if ( return_value == TRUE )
- {
- if ( service_control_manager.EnumerateStatus( SERVICE_INACTIVE ) == TRUE )
- {
- CStringArray stopped_services;
-
- CServiceNameAndStatus status;
-
- while( service_control_manager.GetNext( status ) == TRUE )
- {
- stopped_services.Add( status.lpServiceName );
- }
-
- /*
- ** Now that we have the service names, we need to see which services need to be started
- */
-
- int number_of_stopped_services = stopped_services.GetSize();
- int alive_index = 0;
- int stopped_index = 0;
-
- while( alive_index < number_of_services_to_keep_alive )
- {
- stopped_index = 0;
-
- while( stopped_index < number_of_stopped_services )
- {
- if ( names_of_services_to_keep_alive[ alive_index ].CompareNoCase( stopped_services[ stopped_index ] ) == 0 )
- {
- /*
- ** We found one that died, let's start it
- */
-
- service_control_manager.Start( names_of_services_to_keep_alive[ alive_index ] );
-
- /*
- ** We restarted a service, time to record the event
- */
-
- const char *string_array[ 1 ];
-
- string_array[ 0 ] = (const char *) names_of_services_to_keep_alive[ alive_index ];
-
- CEventLog event_log( "WatchDog" );
- event_log.Report( CEventLog::eventInformation, 0, MSG_WATCHDOG_RESTARTING_SERVICE, 1, (const char **) string_array );
-
- /*
- ** pop out of the loop
- */
-
- stopped_index = number_of_stopped_services;
- }
-
- stopped_index++;
- }
-
- alive_index++;
- }
- }
- }
-
- service_control_manager.Close();
- Sleep( sleep_time );
- }
- while( 1 );
-
- return( 0 );
- }
-
- void set_default_parameters( void )
- {
- CRegistry registry;
-
- if ( registry.Connect( CRegistry::keyLocalMachine ) == TRUE )
- {
- if ( registry.Create( "SYSTEM\\CurrentControlSet\\Services\\WatchDog\\Parameters" ) == TRUE )
- {
- DWORD default_sleep_time = 60;
-
- if ( registry.SetValue( "NumberOfSecondsBetweenChecks", default_sleep_time ) != TRUE )
- {
- LPVOID message_buffer = (LPVOID) NULL;
-
- ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- registry.GetErrorCode(),
- MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
- (LPTSTR) &message_buffer,
- 0,
- NULL );
-
- const char *string_array[ 2 ];
-
- string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\WatchDog\\Parameters\\NumberOfSecondsBetweenChecks";
- string_array[ 1 ] = (const char *) message_buffer;
-
- CEventLog event_log( "WatchDog" );
- event_log.Report( CEventLog::eventError, 0, MSG_CANT_SET_REGISTRY_ENTRY, 2, (const char **) string_array );
-
- if ( message_buffer != NULL )
- {
- ::LocalFree( message_buffer );
- }
- }
-
- CStringArray strings;
-
- strings.RemoveAll();
-
- strings.Add( "" );
-
- if ( registry.SetValue( "Services", strings ) != TRUE )
- {
- LPVOID message_buffer = (LPVOID) NULL;
-
- ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- registry.GetErrorCode(),
- MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
- (LPTSTR) &message_buffer,
- 0,
- NULL );
-
- const char *string_array[ 2 ];
-
- string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\WatchDog\\Parameters\\Services";
- string_array[ 1 ] = (const char *) message_buffer;
-
- CEventLog event_log( "WatchDog" );
- event_log.Report( CEventLog::eventError, 0, MSG_CANT_SET_REGISTRY_ENTRY, 2, (const char **) string_array );
-
- if ( message_buffer != NULL )
- {
- ::LocalFree( message_buffer );
- }
- }
- }
- else
- {
- LPVOID message_buffer = (LPVOID) NULL;
-
- ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- registry.GetErrorCode(),
- MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
- (LPTSTR) &message_buffer,
- 0,
- NULL );
-
- const char *string_array[ 2 ];
-
- string_array[ 0 ] = "SYSTEM\\CurrentControlSet\\Services\\WatchDog\\Parameters";
- string_array[ 1 ] = (const char *) message_buffer;
-
- CEventLog event_log( "WatchDog" );
- event_log.Report( CEventLog::eventError, 0, MSG_CANT_CREATE_REGISTRY_KEY, 2, (const char **) string_array );
-
- if ( message_buffer != NULL )
- {
- ::LocalFree( message_buffer );
- }
- }
- }
- else
- {
- LPVOID message_buffer = (LPVOID) NULL;
-
- ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- registry.GetErrorCode(),
- MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ),
- (LPTSTR) &message_buffer,
- 0,
- NULL );
-
- const char *string_array[ 2 ];
-
- string_array[ 0 ] = "keyLocalMachine";
- string_array[ 1 ] = (const char *) message_buffer;
-
- CEventLog event_log( "WatchDog" );
- event_log.Report( CEventLog::eventError, 0, MSG_CANT_CONNECT_TO_REGISTRY, 2, (const char **) string_array );
-
- if ( message_buffer != NULL )
- {
- ::LocalFree( message_buffer );
- }
- }
- }
-